package tk.pak0.audiomidifier.controller;

import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;

import tk.pak0.audiomidifier.model.audio.AudioTools;
import tk.pak0.audiomidifier.model.midi.MidiTools;
import tk.pak0.audiomidifier.model.persistence.A_DataHolder;
import tk.pak0.audiomidifier.model.persistence.XmlDataHolder;
import tk.pak0.audiomidifier.model.runnable.Metronome;
import tk.pak0.audiomidifier.model.runnable.ThreadControl;

public class Controller {
	private static Controller instance=null;
	
	public AudioTools audioTools;
	public MidiTools midiTools;
	private ResourceBundle properties;
	private Locale locale;
	private String baseName = "tk.pak0.audiomidifier.view.locales.dialogs";
	private A_DataHolder persistence;
	
	public static Controller getInstance(){
		if(instance == null){
			instance = new Controller();
		}
		return instance;
	}
	
	private Controller(){
		try {
			audioTools = AudioTools.getInstance();
			midiTools = MidiTools.getInstance();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
		this.persistence = XmlDataHolder.getInstance();
		locale = Locale.getDefault();
		properties = ResourceBundle.getBundle(baseName, locale);
	}
	
	public String[] getSoundCardsNames(){
		String[] ret = new String[audioTools.getMixersInfo().length];
		for (int i=0; i< ret.length ; i++){
			ret[i] = audioTools.getMixersInfo()[i].getName();
		}
		return ret;
	}
	
	public String[] getInputLinesNamesFromMixerIndex(int mixerIndex){
		String[] ret = new String[audioTools.getLineasEntradasInfo()[mixerIndex].length];
		for (int i=0; i<ret.length ; i++){
			ret[i] = audioTools.getLineasEntradasInfo()[mixerIndex][i].toString();
		}
		return ret;
	}
	
	public String[] getOutputLinesNamesFromMixerIndex(int mixerIndex){
		String[] ret = new String[audioTools.getLineasSalidasInfo()[mixerIndex].length];
		for (int i=0; i<ret.length ; i++){
			ret[i] = audioTools.getLineasSalidasInfo()[mixerIndex][i].toString();
		}
		return ret;
	}
	
	public String[] getMidiLinesNamesFromDevIndex(int devIndex){
		String[] ret = new String[midiTools.getMidiReceivers().get(devIndex).size()];
		for (int i=0; i<ret.length ; i++){
			ret[i] = midiTools.getMidiReceivers().get(devIndex).get(i).toString();
		}
		return ret;
	}
	
	public String[] getMidiDevsNames(){
		String[] ret = new String[midiTools.getMidiDevsInfo().length];
		int realLength = ret.length;
		for(int i=0 ; i< ret.length ; i++){
			if(midiTools.getMidiDevs()[i] != null)
				ret[i] = midiTools.getMidiDevsInfo()[i].getName();
			else{
				ret[i] = "-";
				realLength--;
			}
		}
		return ret;
	}
	
	public String[] getCuantizationModes(){
		String[] modes = new String[]{"4", "4T", "8", "8T", "16", "16T", "32", "32T", "64", "64T"};
		return modes;
	}
	
	public String[] getMetronomeModes(){
		String apagado = properties.getString("swing.metro.combo.option1").trim();
		String visual = properties.getString("swing.metro.combo.option2").trim();
		String sonido = properties.getString("swing.metro.combo.option3").trim();
		String[] modes = new String[]{apagado, visual, sonido};
		return modes;
	}
	
	public String[] getPitchDetectionModes(){
		String[] modes = new String[]{properties.getString("swing.combo.pitchdetection.option1"), properties.getString("swing.combo.pitchdetection.option2"), properties.getString("swing.combo.pitchdetection.option3")};
		return modes;
	}
	
	public Object[] getTessitura(){
		return midiTools.getTessitura().toArray();
	}
	
	public Integer[] getSampleRates(){
		return audioTools.getSampleRates();
	}
	
	public Integer[] getResampleRates(){
		return audioTools.getResampleRates();
	}
	
	public Integer[] getBufferSizes(){
		return audioTools.getBufferSizes();
	}
	
	public ResourceBundle getProperties() {
		return properties;
	}

	public void setProperties(ResourceBundle properties) {
		this.properties = properties;
	}

	public Locale getLocale() {
		return locale;
	}

	public void setLocale(Locale locale) {
		this.locale = locale;
		properties = ResourceBundle.getBundle(this.baseName, locale);
	}
	
	public void setPersistence(Map<String,String> map){
		this.persistence.setValues(map);
	}
	
	public Map<String,String> getPersistence(){
		return this.persistence.getValues();
	}
	
	public void startStop(boolean start){
		ThreadControl threadControl = ThreadControl.getInstance();
		if(start){
			A_DataHolder dataHolder = XmlDataHolder.getInstance();
			// metemos los parámetros de captura
			audioTools.setFrec(getSampleRates()[dataHolder.sampleRate]);
			audioTools.setFormat(new AudioFormat(audioTools.getFrec(), audioTools.getDepth(), audioTools.getChannels(), audioTools.isSigned(), audioTools.isBigEndian()));
			
			if(!dataHolder.liveMode){
				threadControl.setMetronome(true);
				Metronome metronome = threadControl.getMetronome();
				metronome.setBmp(dataHolder.bpm);
				metronome.setAudio(true);
			}else{
				threadControl.setMetronome(false);
			}
			threadControl.fireThreads();
		}else{
			threadControl.killThreads();
		}
	}
	
	public void setLineaEntradaSel(int indexMixer, int indexLine){
		audioTools.setLineaEntradaSel(audioTools.getLineasEntradas()[indexMixer][indexLine]);
	}
	
	public void setLineaSalidaSel(int indexMixer, int indexLine){
		audioTools.setLineaSalidaSel(audioTools.getLineasSalidas()[indexMixer][indexLine]);
	}
	
	public Line getLineaEntradaSel(){
		return audioTools.getLineaEntradaSel();
	}
	
	public Line getLineaSalidaSel(){
		return audioTools.getLineaSalidaSel();
	}
}
